home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / biblio / bibtex / utils / refer-tools / refer-to-bibtex.el < prev    next >
Lisp/Scheme  |  1992-07-01  |  18KB  |  576 lines

  1. ;From michael@uni-paderborn.de Thu Jul 12 07:25:01 1990
  2. ;Return-Path: <michael@uni-paderborn.de>
  3. ;Received: from mcsun.EU.net by life.ai.mit.edu (4.1/AI-4.10) id AA23180; Thu, 12 Jul 90 07:24:37 EDT
  4. ;Received: by mcsun.EU.net with SMTP; Thu, 12 Jul 90 13:24:18 +0200 (MET)
  5. ;Received: from athene.uni-paderborn.de 
  6. ;    by unido.informatik.uni-dortmund.de with SMTP via EUnet (UNIDO-2.0.1.q) via EUnet
  7. ;    for wheaties.ai.mit.edu
  8. ;    id AK07977; Thu, 12 Jul 90 10:58:24 +0100
  9. ;Received: by athene.uni-paderborn.de; Thu, 12 Jul 90 10:55:58 +0200 (PB-3.13)
  10. ;Date: Thu, 12 Jul 90 10:55:58 +0200
  11. ;From: Michael Schmidt <michael@uni-paderborn.de>
  12. ;Message-Id: <9007120855.AA04022@athene.uni-paderborn.de>
  13. ;To: tmb@wheaties.ai.mit.edu (Thomas M. Breuel)
  14. ;Subject: Re: BibTex <-> Tib/Refer converter wanted
  15. ;Newsgroups: comp.text.tex,comp.text
  16. ;In-Reply-To: Your message of 30 Jun 90 00:08:58 GMT in comp.text.tex,comp.text
  17. ;Organization: Replace me with your organization
  18. ;Status: R
  19. ;
  20. ;In article <9290@life.ai.mit.edu> you write:
  21. ;>I am looking for a converter to convert BibTex bibliography files
  22. ;>to Tib/Refer files and vice versa.
  23. ;
  24. ;What about a little emacs miracle (GNU, of course).
  25. ;
  26. ;    Michael
  27. ;
  28. ;--
  29. ; LAST EDIT: Thu Jan 12 22:47:18 1989 by Michael Schmidt (schmidt) 
  30. ;; refer-to-bibtex.el
  31. ;; Convert refer-style bibliographic entries to ones usable by latex bib 
  32. ;; copyright 1988 Henry Kautz
  33. ;;
  34. ;; Use: from a buffer containing the refer-style bibliography,
  35. ;;   M-x r2b-convert-buffer
  36. ;; Program will prompt for an output buffer name, and will log
  37. ;; warnings during the conversion process in the buffer *Log*.
  38.  
  39. (provide 'refer-to-bibtex)
  40. ;**********************************************************
  41. ; User Parameters
  42.  
  43. (defvar r2b-trace-on nil "*trace conversion")
  44.  
  45. (defvar r2b-journal-abbrevs
  46.    '(  ("aij" "{Artificial Intelligence}")
  47.        )
  48.    "Abbreviation list for journal names.  
  49. If the car of an element matches the data exactly, it is replaced by
  50. the cadr when output.  Braces must be included if replacement is a
  51. {string}, but not if replacement is a bibtex abbreviation.  The cadr
  52. may be eliminated if is exactly the same as the car.")
  53.  
  54. (defvar r2b-booktitle-abbrevs 
  55.    '(  ("mi" "{Machine Intelligence}") 
  56.        ("aaai88" "{Proceedings of AAAI-88}")
  57.        ("ijcai88")
  58.        )
  59.    "Abbreviation list for book and proceedings names.  If the car of
  60. an element matches the data exactly, it is replaced by the cadr when
  61. output.  Braces must be included if replacement is a {string}, but not
  62. if replacement is a bibtex abbreviation.  The cadr may be eliminated
  63. if is exactly the same as the car.  
  64.     For example, the default value means that aaai88 is expanded
  65. to ordinary test, but ijcai88 is treated as a bibtex macro.")
  66.  
  67. (defvar r2b-proceedings-list
  68.    '(("ijcai88"))
  69.    "Assoc list of books or journals which are really conference proceedings,
  70. but whose name and whose abbrev expansion (as defined in r2b-journal-abbrevs
  71. and r2b-booktitle-abbrevs) does not contain the words 'conference' or
  72. 'proceeding'.  (Those cases are handled automatically.)
  73. The entry must match the given data exactly.")
  74.  
  75. (defvar r2b-stop-words
  76.      "A\\|The\\|Some\\|\\An"
  77.    "Words not considered to use to build the citation key")
  78.  
  79. ;**********************************************************
  80. ; Utility Functions
  81.  
  82. (setq capitalize-title-stop-words
  83.    (concat 
  84.       "\\(the\\|and\\|of\\|is\\|a\\|an\\|of\\|for\\|in\\|to\\|in\\|on\\|at\\|"
  85.       "by\\|with\\|that\\|its\\)\\b"))
  86.  
  87. (defun capitalize-title-region (begin end)
  88.    "Like capitalize-region, but don't capitalize stop words, except the first"
  89.    (interactive "r")
  90.    (let ((case-fold-search t))
  91.       (save-restriction
  92.      (narrow-to-region begin end)
  93.      (goto-char (point-min))
  94.      (capitalize-word 1)
  95.      (while (re-search-forward "\\<" nil t)
  96.         (if (looking-at capitalize-title-stop-words)
  97.            (downcase-word 1)
  98.            (if (let ((case-fold-search nil)) (looking-at ".[A-Z]"))
  99.           (forward-word 1)
  100.           (capitalize-word 1)))
  101.         )
  102.      )))
  103.  
  104. (defun capitalize-title (s)
  105.    "Like capitalize, but don't capitalize stop words, except the first"
  106.    (save-excursion
  107.       (set-buffer (get-buffer-create "$$$Scratch$$$"))
  108.       (erase-buffer)
  109.       (insert s)
  110.       (capitalize-title-region (point-min) (point-max))
  111.       (buffer-string)))
  112.  
  113. ;*********************************************************
  114. (defun r2b-reset ()
  115.    "unbind defvars, for debugging"
  116.    (interactive)
  117.    (makunbound 'r2b-journal-abbrevs)
  118.    (makunbound 'r2b-booktitle-abbrevs)
  119.    (makunbound 'r2b-proceedings-list)
  120.    (makunbound 'r2b-stop-words)
  121.    (makunbound 'r2b-stop-regexp)
  122.    )
  123.  
  124. (defvar r2b-stop-regexp
  125.    (concat "\\(\\(" r2b-stop-words "\\|\\)\\b\\)[ \t\n]*\\([A-Z0-9]+\\)"))
  126.  
  127.  
  128. (defun r2b-trace (&rest args)
  129.    (if r2b-trace-on
  130.       (progn
  131.      (apply (function message) args)
  132.      (sit-for 0)
  133.      )))
  134.  
  135. (defun r2b-match (exp)
  136.    "returns string matched in current buffer"
  137.    (buffer-substring (match-beginning exp) (match-end exp)))
  138.  
  139. (defvar r2b-out-buf-name "*Out*" "*output from refer-to-bibtex" )
  140. (defvar r2b-log-name "*Log*" "*logs errors from refer-to-bibtex" )
  141. (defvar r2b-in-buf nil)
  142. (defvar r2b-out-buf nil)
  143. (defvar r2b-log nil)
  144.  
  145. (defvar r2b-error-found nil)
  146.  
  147. (setq r2b-variables '(
  148.             r2b-error-found
  149.               r2bv-author
  150.               r2bv-primary-author
  151.               r2bv-date
  152.               r2bv-year
  153.               r2bv-decade
  154.               r2bv-month
  155.               r2bv-title
  156.               r2bv-title-first-word
  157.               r2bv-editor
  158.               r2bv-annote
  159.               r2bv-tr
  160.               r2bv-address
  161.               r2bv-institution
  162.               r2bv-keywords
  163.               r2bv-booktitle
  164.               r2bv-journal
  165.               r2bv-volume
  166.               r2bv-number
  167.               r2bv-pages
  168.               r2bv-booktitle
  169.               r2bv-kn
  170.               r2bv-publisher
  171.               r2bv-school
  172.               r2bv-type
  173.               r2bv-where
  174.               r2bv-note
  175.               ))
  176.  
  177. (defun r2b-clear-variables ()
  178.    "set all global vars used by r2b to nil"
  179.    (let ((vars r2b-variables))
  180.       (while vars
  181.      (set (car vars) nil)
  182.      (setq vars (cdr vars)))
  183.       ))
  184.  
  185. (defun r2b-warning (&rest args)
  186.    (setq r2b-error-found t)
  187.    (princ (apply (function format) args) r2b-log)
  188.    (princ "\n" r2b-log))
  189.  
  190. (defun r2b-get-field (var field &optional unique required)
  191.    "Set VAR to string value of FIELD, if any.  If none, VAR is set to nil.
  192. If multiple fields appear, then separate values with the '\\nand\\t\\t',
  193. unless UNIQUE is non-nil, in which case log error and return first value.
  194. Trim off leading blanks and tabs on first line, and
  195. trailing blanks and tabs of every line.
  196. Returns value of var."
  197.    (let (item val (not-past-end t))
  198.       (r2b-trace "snarfing %s" field)
  199.       (goto-char (point-min))
  200.       (while (and not-past-end
  201.         (re-search-forward 
  202.            (concat "^" field "\\b[ \t]*\\(.*\\)") nil t))
  203.      (setq item (r2b-match 1))
  204.      (while (and (setq not-past-end (zerop (forward-line 1)))
  205.            (not (looking-at "[ \t]*$\\|%")))
  206.            (looking-at "\\(.*[^ \t\n]\\)[ \t]*$")
  207.            (setq item (concat item "\n" (r2b-match 1)))
  208.         )
  209.      (if (null val)
  210.         (setq val item)
  211.         (if unique
  212.            (r2b-warning "*Illegal multiple field %s %s" field item)
  213.            (setq val (concat val "\n\t\tand " item))
  214.            )
  215.         )
  216.      )
  217.       (if (and (null val) required)
  218.      (r2b-warning "*Missing field %s" field))
  219.       (set var val)
  220.       ))
  221.  
  222. (defun r2b-set-match (var n regexp string )
  223.    "set VAR to the Nth subpattern in REGEXP matched by STRING, or nil if none"
  224.    (set var
  225.       (if (and (stringp string) (string-match regexp string))
  226.      (substring string (match-beginning n) (match-end n))
  227.      nil)
  228.       )
  229.    )
  230.  
  231. (defvar r2b-month-abbrevs
  232.    '(("jan") ("feb") ("mar") ("apr") ("may") ("jun") ("jul") ("aug")
  233.        ("sep") ("oct") ("nov") ("dec")))
  234.  
  235. (defun r2b-convert-month ()
  236.    "Try to convert r2bv-month to a standard 3 letter name"
  237.    (if r2bv-month
  238.       (let ((months r2b-month-abbrevs))
  239.      (if (string-match "[^0-9]" r2bv-month)
  240.         (progn
  241.            (while (and months (not (string-match (car (car months)) 
  242.                       r2bv-month)))
  243.           (setq months (cdr months)))
  244.            (if months
  245.           (setq r2bv-month (car (car months)))))
  246.         (progn
  247.            (setq months (car (read-from-string r2bv-month)))
  248.            (if (and (numberp months)
  249.               (> months 0)
  250.               (< months 13))
  251.           (setq r2bv-month (car (nth months r2b-month-abbrevs)))
  252.           (progn
  253.              (r2b-warning "* Ridiculous month")
  254.              (setq r2bv-month nil))
  255.           ))
  256.         ))
  257.       )
  258.    )
  259.  
  260. (defun r2b-snarf-input ()
  261.    "parse buffer into global variables"
  262.    (let ((case-fold-search t))
  263.       (r2b-trace "snarfing...")
  264.       (sit-for 0)
  265.       (set-buffer r2b-in-buf)
  266.       (goto-char (point-min))
  267.       (princ "    " r2b-log)
  268.       (princ (buffer-substring (point) (progn (end-of-line) (point))) r2b-log)
  269.       (terpri r2b-log)
  270.  
  271.       (r2b-get-field 'r2bv-author "%A" nil t)
  272.       (r2b-set-match 'r2bv-primary-author 1
  273.      "\\b\\(\\w+\\)[ \t]*\\($\\|,\\)" r2bv-author)
  274.  
  275.       (r2b-get-field 'r2bv-date "%D" t t)
  276.       (r2b-set-match 'r2bv-year 0 "[12][0-9][0-9][0-9]" r2bv-date)
  277.       (and (null r2bv-year)
  278.      (r2b-set-match 'r2bv-year 1 "[^0-9]\\([0-9][0-9]\\)$" r2bv-date)
  279.      (setq r2bv-year (concat "19" r2bv-year)))
  280.       (r2b-set-match 'r2bv-decade 1 "..\\(..\\)" r2bv-year)
  281.       (r2b-set-match 'r2bv-month 0
  282.      "[0-9]+/\\|[a-zA-Z]+" r2bv-date)
  283.       (if (and (stringp r2bv-month) (string-match "\\(.*\\)/$" r2bv-month))
  284.      (setq r2bv-month (substring r2bv-month 0 (match-end 1))))
  285.       (r2b-convert-month)
  286.  
  287.       (r2b-get-field 'r2bv-title "%T" t t)
  288.       (r2b-require 'r2bv-title)
  289.       (setq r2bv-title (capitalize-title r2bv-title))
  290.       (r2b-set-match 'r2bv-title-first-word 3
  291.      r2b-stop-regexp
  292.      r2bv-title)
  293.       
  294.  
  295.       (r2b-get-field 'r2bv-editor "%E")
  296.       (r2b-get-field 'r2bv-annote "%X" t )
  297.       (r2b-get-field 'r2bv-tr "%R" t)
  298.       (r2b-get-field 'r2bv-address "%C" t)
  299.       (r2b-get-field 'r2bv-institution "%I" t)
  300.       (r2b-get-field 'r2bv-keywords "%K")
  301.       (r2b-get-field 'r2bv-booktitle "%B" t)
  302.       (r2b-get-field 'r2bv-journal "%J" t)
  303.       (r2b-get-field 'r2bv-volume "%V" t)
  304.       (r2b-get-field 'r2bv-number "%N" t)
  305.       (r2b-get-field 'r2bv-pages "%P" t)
  306.       (r2b-get-field 'r2bv-where "%W" t)
  307.       )
  308.    )
  309.  
  310.  
  311. (defun r2b-put-field (field data &optional abbrevs)
  312.    "print bibtex FIELD = {DATA} if DATA not null; precede
  313. with a comma and newline; if ABBREVS list is given, then
  314. try to replace the {DATA} with an abbreviation"
  315.    (if data
  316.       (let (match nodelim multi-line)
  317.      (if (and abbrevs (setq match (assoc data abbrevs)))
  318.         (progn
  319.            (if (null (cdr match))
  320.           (setq data (car match))
  321.           (setq data (car (cdr match))))
  322.            (setq nodelim t)))
  323.      (if (and (not (equal data ""))
  324.         (not (string-match "[^0-9]" data)))
  325.         (setq nodelim t))
  326.      (princ ", \n  ")
  327.      (princ field)
  328.      (princ " =\t")
  329.      (if (not nodelim) (princ "{"))
  330.      (string-match ".*" data)
  331.      (if (> (match-end 0) 59)
  332.         (princ "\n"))
  333.      (princ data)
  334.      (if (not nodelim) (princ "}"))
  335.      )
  336.       ))
  337.  
  338.  
  339. (defun r2b-require (vars)
  340.    "If any of VARS is null, set to empty string and log error"
  341.    (cond 
  342.       ((null vars))
  343.       ((listp vars) (r2b-require (car vars)) (r2b-require (cdr vars)))
  344.       (t
  345.      (if (null (symbol-value vars))
  346.         (progn
  347.            (r2b-warning "*Missing value for field %s" vars)
  348.            (set vars "")
  349.            )))
  350.       )
  351.    )
  352.  
  353.  
  354. (defmacro moveq (new old)
  355.    "set NEW to OLD and set OLD to nil"
  356.    (list 'progn (list 'setq new old) (list 'setq old 'nil)))
  357.  
  358. (defun r2b-barf-output ()
  359.    "generate bibtex based on global variables"
  360.    (let ((standard-output r2b-out-buf) (case-fold-search t) match)
  361.  
  362.       (r2b-trace "...barfing")
  363.       (sit-for 0)
  364.       (set-buffer r2b-out-buf)
  365.  
  366.       (setq r2bv-kn (concat r2bv-primary-author r2bv-decade
  367.             r2bv-title-first-word))
  368.       
  369.       (setq r2bv-entry-kind
  370.      (cond 
  371.         ((and r2bv-journal
  372.         (or 
  373.            (string-match "proceeding\\|conference" r2bv-journal)
  374.            (assoc r2bv-journal r2b-proceedings-list)
  375.            (and 
  376.               (setq match (assoc r2bv-journal r2b-booktitle-abbrevs))
  377.               (string-match "proceeding\\|conference" 
  378.              (car (cdr (match)))))))
  379.            (moveq r2bv-booktitle r2bv-journal)
  380.            (moveq r2bv-publisher r2bv-institution)
  381.            'inproceedings)
  382.         ((and r2bv-booktitle
  383.         (or 
  384.            (string-match "proceeding\\|conference" r2bv-booktitle)
  385.            (assoc r2bv-booktitle r2b-proceedings-list)
  386.            (and 
  387.               (setq match (assoc r2bv-booktitle 
  388.                        r2b-booktitle-abbrevs))
  389.               (string-match "proceeding\\|conference" 
  390.              (car (cdr (match)))))))
  391.            (moveq r2bv-publisher r2bv-institution)
  392.            'inproceedings)
  393.         ((and r2bv-tr (string-match "phd" r2bv-tr))
  394.            (moveq r2bv-school r2bv-institution)
  395.            (r2b-require 'r2bv-school )
  396.            'phdthesis)
  397.         ((and r2bv-tr (string-match "master" r2bv-tr))
  398.            (moveq r2bv-school r2bv-institution)
  399.            (r2b-require 'r2bv-school )
  400.            'mastersthesis)
  401.         ((and r2bv-tr (string-match "draft\\|unpublish" r2bv-tr))
  402.            (moveq r2bv-note r2bv-institution)
  403.            'unpublished)
  404.         (r2bv-journal
  405.            'article)
  406.         (r2bv-booktitle
  407.            (moveq r2bv-publisher r2bv-institution)
  408.            (r2b-require 'r2bv-publisher)
  409.            'incollection)
  410.         (r2bv-tr
  411.            (r2b-require 'r2bv-institution)
  412.            (if (string-match "\\(.+\\)[ /t/n]+\\([^ /t/n]\\)+$" 
  413.               r2bv-tr)
  414.           (progn
  415.              (setq r2bv-type (substring r2bv-tr 0 (match-end 1)))
  416.              (setq r2bv-number (substring r2bv-tr 
  417.                       (match-beginning 2)))
  418.              (setq r2bv-tr nil))
  419.           (moveq r2bv-number r2bv-tr))
  420.            'techreport)
  421.         (r2bv-institution
  422.            (moveq r2bv-publisher r2bv-institution)
  423.            (r2b-require 'r2bv-publisher)
  424.            'book)
  425.         (t
  426.            'misc)
  427.         ))
  428.  
  429.       (r2b-require '(r2bv-author r2bv-title r2bv-year))
  430.  
  431.       (if r2b-error-found
  432.      (princ "\n% Warning -- Errors During Conversion Next Entry\n"))
  433.  
  434.       (princ "\n@")
  435.       (princ r2bv-entry-kind)
  436.       (princ "( ")
  437.       (princ r2bv-kn)
  438.  
  439.       (r2b-put-field "author" r2bv-author )
  440.       (r2b-put-field "title" r2bv-title )
  441.       (r2b-put-field "year" r2bv-year )
  442.  
  443.       (r2b-put-field "month" r2bv-month r2b-month-abbrevs)
  444.       (r2b-put-field "journal" r2bv-journal r2b-journal-abbrevs)
  445.       (r2b-put-field "volume" r2bv-volume)
  446.       (r2b-put-field "number" r2bv-number)
  447.       (r2b-put-field "type" r2bv-type)
  448.       (r2b-put-field "booktitle" r2bv-booktitle r2b-booktitle-abbrevs)
  449.       (r2b-put-field "editor" r2bv-editor)
  450.       (r2b-put-field "publisher" r2bv-publisher)
  451.       (r2b-put-field "institution" r2bv-institution)
  452.       (r2b-put-field "school" r2bv-school)
  453.       (r2b-put-field "pages" r2bv-pages)
  454.       (r2b-put-field "address" r2bv-address)
  455.       (r2b-put-field "note" r2bv-note)
  456.       (r2b-put-field "keywords" r2bv-keywords)
  457.       (r2b-put-field "where" r2bv-where)
  458.       (r2b-put-field "annote" r2bv-annote)
  459.  
  460.       (princ " )\n")
  461.       )
  462.    )
  463.  
  464.  
  465. (defun r2b-convert-record (output-name)
  466.    "transform current bib entry and append to buffer OUTPUT"
  467.    (interactive 
  468.       (list (read-string "Output to buffer: " r2b-out-buf-name)))
  469.    (let (rec-end rec-begin not-done)
  470.       (setq r2b-out-buf-name output-name)
  471.       (setq r2b-out-buf (get-buffer-create output-name))
  472.       (setq r2b-in-buf (current-buffer))
  473.       (set-buffer r2b-out-buf)
  474.       (goto-char (point-max))
  475.       (setq r2b-log (get-buffer-create r2b-log-name))
  476.       (set-buffer r2b-log)
  477.       (goto-char (point-max))
  478.       (set-buffer r2b-in-buf)
  479.       (setq not-done (re-search-forward "[^ \t\n]" nil t))
  480.       (if not-done
  481.      (progn
  482.         (re-search-backward "^[ \t]*$" nil 2)
  483.         (re-search-forward "^%")
  484.         (beginning-of-line nil)
  485.         (setq rec-begin (point))
  486.         (re-search-forward "^[ \t]*$" nil 2)
  487.         (setq rec-end (point))
  488.         (narrow-to-region rec-begin rec-end)
  489.         (r2b-clear-variables)
  490.         (r2b-snarf-input)
  491.         (r2b-barf-output)
  492.         (set-buffer r2b-in-buf)
  493.         (widen)
  494.         (goto-char rec-end)
  495.         t)
  496.      nil
  497.      )
  498.       ))
  499.       
  500.       
  501. (defun r2b-convert-buffer (output-name)
  502.    "transform current buffer and append to buffer OUTPUT"
  503.    (interactive 
  504.       (list (read-string "Output to buffer: " r2b-out-buf-name)))
  505.    (save-excursion
  506.       (setq r2b-log (get-buffer-create r2b-log-name))
  507.       (set-buffer r2b-log)
  508.       (erase-buffer))
  509.    (widen)
  510.    (goto-char (point-min))
  511.    (message "Working, please be patient...")
  512.    (sit-for 0)
  513.    (while (r2b-convert-record output-name) t)
  514.    (message "Done, results in %s, errors in %s" 
  515.       r2b-out-buf-name r2b-log-name)
  516.    )
  517.  
  518. (defvar r2b-load-quietly nil "*Don't print help message when loaded")
  519.  
  520. (defvar r2b-help-message
  521. "                   Refer to Bibtex Bibliography Conversion
  522.  
  523. A refer-style database is of the form:
  524.  
  525. %A Joe Blow
  526. %T Great Thoughts I've Thought
  527. %D 1977
  528. etc.
  529.  
  530. This utility converts these kind of databases to bibtex form, for
  531. users of TeX and LaTex.  Instructions:
  532. 1.  Visit the file containing the refer-style database.
  533. 2.  The command
  534.     M-x r2b-convert-buffer
  535.     converts the entire buffer, appending it's output by default in a
  536.     buffer named *Out*, and logging progress and errors in a buffer
  537.     named *Log*.  The original file is never modified.
  538.     Note that results are appended to *Out*, so if that buffer
  539.     buffer already exists and contains material you don't want to
  540.      save, you should kill it first.
  541. 3.  Switch to the buffer *Out* and save it as a named file.
  542. 4.  To convert a single refer-style entry, simply position the cursor
  543.     at the entry and enter
  544.     M-x r2b-convert-record
  545.     Again output is appended to *Out* and errors are logged in *Log*.
  546.  
  547. This utility is very robust and pretty smart about determining the
  548. type of the entry.  It includes facilities for expanding refer macros
  549. to text, or substituting bibtex macros.  See the source file,
  550.     refer-to-bibtex.el
  551. for information on how to customize the conversion process.
  552.  
  553. If you don't want to see this help message when you load this utility,
  554. then include the following line in your .emacs file:
  555.     (setq r2b-load-quietly t)
  556.  
  557. Please send bug reports and suggestions to
  558.     Henry Kautz
  559.     allegra!kautz
  560.     kautz@allegra.att.com")
  561.  
  562.  
  563. (defun r2b-help ()
  564.    "print help message"
  565.    (interactive)
  566.    (with-output-to-temp-buffer "*Help*"
  567.       (princ r2b-help-message)))
  568.  
  569. (if (not r2b-load-quietly)
  570.    (r2b-help))
  571.  
  572. (message "r2b loaded")
  573. -- 
  574.     Michael
  575.  
  576.